import axios from 'axios';
import { authEventManager } from '../lib/auth-events';

// 扣子预览环境域名白名单
const COZE_PREVIEW_DOMAINS = [
  '*.coze.cn',
  '*.coze.com',
  '*.cozeapp.cn',
  '*.cozeapp.com'
];

const api = axios.create({
  timeout: 10000,
  baseURL: 'https://apiiot.hongyanyun.cn',
  headers: {
    'Accept': 'application/json, text/plain, */*',
    'Accept-Language': 'zh-CN,zh;q=0.9',
    'Content-Type': 'application/json',
    'Access-Control-Allow-Methods': 'POST, OPTIONS',
    'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-Requested-With'
  },
  method: 'post',
  withCredentials: false
});

// 创建不需要认证的API实例，用于分享页面
const publicApi = axios.create({
  timeout: 10000,
  baseURL: 'https://apiiot.hongyanyun.cn',
  headers: {
    'Accept': 'application/json, text/plain, */*',
    'Accept-Language': 'zh-CN,zh;q=0.9',
    'Content-Type': 'application/json',
    'Access-Control-Allow-Methods': 'POST, OPTIONS',
    'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-Requested-With'
  },
  method: 'post',
  withCredentials: false
});

// 请求拦截器
api.interceptors.request.use(config => {
  // 强制所有请求使用POST方法
  config.method = 'post';
  
  // 添加Authorization头
  const token = localStorage.getItem('token');
  if (token && config.headers) {
    config.headers['Authorization'] = token;
    config.headers['Content-Type'] = 'application/json';
    config.headers['X-Requested-With'] = 'XMLHttpRequest';
  }

  // 确保使用HTTPS
  if (config.url?.startsWith('http://')) {
    config.url = config.url.replace('http://', 'https://');
  }

  return config;
}, error => {
  console.error('Request interceptor error:', error);
  return Promise.reject({
    message: '请求配置错误',
    details: error,
    isRequestError: true
  });
});

// 公共API请求拦截器（不需要认证）
publicApi.interceptors.request.use(config => {
  // 强制所有请求使用POST方法
  config.method = 'post';
  
  // 确保使用HTTPS
  if (config.url?.startsWith('http://')) {
    config.url = config.url.replace('http://', 'https://');
  }

  return config;
}, error => {
  console.error('Public API request interceptor error:', error);
  return Promise.reject({
    message: '请求配置错误',
    details: error,
    isRequestError: true
  });
});

// 响应拦截器
api.interceptors.response.use(
  response => {
    if (response.data?.code === 401) {
      handle401Error(response.data?.message);
      return Promise.reject(response.data);
    }
    return response.data;
  },
  error => {
    let errorMessage = '网络错误';
    let isNetworkError = false;
    let isCorsError = false;
    
    if (error.code === 'ECONNABORTED') {
      errorMessage = '请求超时，请检查网络连接';
      isNetworkError = true;
    } else if (error.response) {
      if (error.response.status === 0) {
        errorMessage = `跨域请求被阻止，请检查：
1. 服务器CORS配置是否允许当前域名: ${window.location.origin}
2. 服务器是否支持OPTIONS预检请求
3. 是否正确返回以下头信息:
   - Access-Control-Allow-Origin: ${window.location.origin}
   - Access-Control-Allow-Methods: POST, OPTIONS
   - Access-Control-Allow-Headers: Content-Type, Authorization`;
        isCorsError = true;
      } else if (error.response.status === 401 || error.response.data?.code === 401) {
        handle401Error(error.response.data?.message);
        errorMessage = error.response.data?.message || '未授权，请重新登录';
      } else {
        errorMessage = error.response.data?.message || `服务器错误 (${error.response.status})`;
      }
    } else if (error.request) {
      errorMessage = `无法连接到服务器(${api.defaults.baseURL})，请检查：
1. 网络连接
2. 服务器地址是否正确
3. 服务器是否运行正常`;
      isNetworkError = true;
    }

    if (error.isCorsError || error.message?.includes('cross-origin') || error.message?.includes('CORS')) {
      errorMessage = `跨域请求失败，请确保服务器已配置允许来自 ${window.location.origin} 的请求，并支持OPTIONS预检请求。
      
解决方案:
1. 联系后端开发人员检查服务器CORS配置
2. 确保服务器响应中包含以下头信息:
   - Access-Control-Allow-Origin: ${window.location.origin}
   - Access-Control-Allow-Methods: POST, OPTIONS
   - Access-Control-Allow-Headers: Content-Type, Authorization`;
      isCorsError = true;
    }

    console.error('API Error:', {
      message: error.message,
      code: error.code,
      config: error.config,
      response: error.response,
      request: error.request,
      isNetworkError,
      isCorsError
    });

    return Promise.reject({
      status: error.response?.status || 0,
      message: errorMessage,
      data: error.response?.data,
      isNetworkError,
      isCorsError,
      config: error.config
    });
  }
);

// 公共API响应拦截器（不需要认证）
publicApi.interceptors.response.use(
  response => {
    return response.data;
  },
  error => {
    let errorMessage = '网络错误';
    let isNetworkError = false;
    let isCorsError = false;
    
    if (error.code === 'ECONNABORTED') {
      errorMessage = '请求超时，请检查网络连接';
      isNetworkError = true;
    } else if (error.response) {
      if (error.response.status === 0) {
        errorMessage = `跨域请求被阻止，请检查：
1. 服务器CORS配置是否允许当前域名: ${window.location.origin}
2. 服务器是否支持OPTIONS预检请求
3. 是否正确返回以下头信息:
   - Access-Control-Allow-Origin: ${window.location.origin}
   - Access-Control-Allow-Methods: POST, OPTIONS
   - Access-Control-Allow-Headers: Content-Type, Authorization`;
        isCorsError = true;
      } else {
        errorMessage = error.response.data?.message || `服务器错误 (${error.response.status})`;
      }
    } else if (error.request) {
      errorMessage = `无法连接到服务器(${publicApi.defaults.baseURL})，请检查：
1. 网络连接
2. 服务器地址是否正确
3. 服务器是否运行正常`;
      isNetworkError = true;
    }

    if (error.isCorsError || error.message?.includes('cross-origin') || error.message?.includes('CORS')) {
      errorMessage = `跨域请求失败，请确保服务器已配置允许来自 ${window.location.origin} 的请求，并支持OPTIONS预检请求。
      
解决方案:
1. 联系后端开发人员检查服务器CORS配置
2. 确保服务器响应中包含以下头信息:
   - Access-Control-Allow-Origin: ${window.location.origin}
   - Access-Control-Allow-Methods: POST, OPTIONS
   - Access-Control-Allow-Headers: Content-Type, Authorization`;
      isCorsError = true;
    }

    console.error('Public API Error:', {
      message: error.message,
      code: error.code,
      config: error.config,
      response: error.response,
      request: error.request,
      isNetworkError,
      isCorsError
    });

    return Promise.reject({
      status: error.response?.status || 0,
      message: errorMessage,
      data: error.response?.data,
      isNetworkError,
      isCorsError,
      config: error.config
    });
  }
);

function handle401Error(message?: string) {
  localStorage.removeItem('token');
  // 触发认证失效事件，让App组件处理导航
  authEventManager.triggerAuthFailure();
  if (message) {
    console.error('401 Error:', message);
  }
}

export function withRetry<T extends (...args: any[]) => any>(
  fn: T, 
  retries = 2, 
  delay = 1000
) {
  return async function(...args: Parameters<T>) {
    let lastError: any;
    for (let i = 0; i < retries; i++) {
      try {
        return await fn(...args);
      } catch (error) {
        lastError = error;
        if (i < retries - 1) {
          await new Promise(res => setTimeout(res, delay));
        }
      }
    }
    throw lastError;
  };
}

// 检查登录状态接口
export const checkLogin = async () => {
  try {
    const res = await api({
      url: '/doc/user/checkLogin',
      method: 'post',
      data: {},
      timeout: 3000 // 减少超时时间到3秒
    });
    
    if (!res) {
      throw new Error('未收到服务器响应');
    }
    
    // 处理响应数据
    const responseData = res as any;
    if (responseData.code !== 200 || !responseData.success) {
      const errorMsg = responseData.message || responseData.localizedMsg || '登录状态检查失败';
      throw new Error(errorMsg);
    }
    
    return responseData.data === true;
  } catch (error: any) {
    console.error('检查登录状态错误:', error);
    return false;
  }
};

export interface ApiResponse<T = any> {
  code: number;
  success: boolean;
  message?: string;
  data?: T;
  [key: string]: any;
}

/**
 * 添加文档历史版本
 * @param params { docId, docContent, diffContent, isCurrent, contentHash }
 */
export const addVersion = async (params: {
  docId: string;
  docContent: string;
  diffContent: string;
  isCurrent: boolean;
  contentHash: string;
}) => {
  return api({
    url: '/doc/version/addVersion',
    method: 'post',
    data: params,
    timeout: 10000
  });
};

export default api;
export { publicApi };
